﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

namespace GetWebInfo
{
    struct DividendInfo
    {
        /// <summary>
        /// 每股分红
        /// </summary>
        public decimal DividendPerShare;

        /// <summary>
        /// 每股送股
        /// </summary>
        public decimal SplitPerShare;

        /// <summary>
        /// 分红总金额
        /// </summary>
        public decimal Dividends;
    }

    class Dividend
    {
        /* Dividend 文件格式
         * ***************************************************************************
         * 2011-04-26,A:8014419900,DP,0.2,SP,0.3
         * 2012-06-31,A:8014419900,DP,0.2,SP,0.3
         * ***************************************************************************
         * 除权日起,派现金额,每股派现,每股送股
         */
        public Dividend()
        {
        }

        public SortedList<DateTime, DividendInfo> Dividends
        {
            get
            {
                return this._dividends;
            }
        }
        private SortedList<DateTime, DividendInfo> _dividends = new SortedList<DateTime, DividendInfo>();

        public void Save(string stockCode)
        {
            if (stockCode.Length != 6)
            {
                Console.WriteLine("The stockCode is empty!");
                return;
            }
            string _filePath = string.Format(@"{0}\{1}\{2}",
                System.AppDomain.CurrentDomain.BaseDirectory,
                stockCode,
                Const.DividendFileName);

            StreamWriter _sw = new StreamWriter(_filePath, false, Encoding.Default);
            foreach (KeyValuePair<DateTime, DividendInfo> kvp in _dividends)
            {
                _sw.WriteLine(string.Format("{0},A:{1},DP:{2},SP:{3}",
                        kvp.Key.ToString("yyyy-MM-dd"),
                        kvp.Value.Dividends,
                        kvp.Value.DividendPerShare,
                        kvp.Value.SplitPerShare));
            }
            
            _sw.Close();
        }

        public static Dividend Load(string stockCode)
        {
            if (stockCode.Length != 6)
            {
                Console.WriteLine("The stockCode is empty!");
                return null;
            }
            string _filePath = string.Format(@"{0}\{1}\{2}",
                System.AppDomain.CurrentDomain.BaseDirectory,
                stockCode,
                Const.DividendFileName);

            if (!File.Exists(_filePath))
            {
                return null;
            }

            Dividend _sp = new Dividend();
            using (StreamReader sr = new StreamReader(_filePath))
            {
                string line;

                while ((line = sr.ReadLine()) != null)
                {
                    if (line != "")
                    {
                        string[] _strs = line.Split(new char[] { ',', ':' });
                        _sp._dividends.Add(DateTime.Parse(_strs[0]), new DividendInfo
                        {
                            Dividends = decimal.Parse(_strs[2]),
                            DividendPerShare = decimal.Parse(_strs[4]),
                            SplitPerShare = decimal.Parse(_strs[6])
                        });
                    }                    
                }
            }

            return _sp;
        }

        /// <summary>
        /// 解析和讯分红报表，并返回Dividend结构
        /// </summary>
        /// <param name="stockCode"></param>
        /// <returns></returns>
        public static void Parse(string stockCode)
        {
            if (stockCode.Length != 6)
            {
                Console.WriteLine("The stockCode is empty!");
                return;
            }
            string _directoryPath = string.Format(@"{0}\{1}", System.AppDomain.CurrentDomain.BaseDirectory, stockCode);
            if (!Directory.Exists(_directoryPath))
            {
                Directory.CreateDirectory(_directoryPath);
            }

            WebClient _myWebClient = new WebClient();
            string _myWebInfo1 = string.Empty;

            string _urlPath = string.Format(Const.PagePath_HexunDividend, stockCode);

            if (Const.OnlyTest) _urlPath = @"H:\forge\自动下载程序的需求\exe\600016-test\fhzzgb";

            Console.WriteLine("Parse the hexun dividendpage is: [{0}]", _urlPath);
            _myWebInfo1 = Encoding.Default.GetString(_myWebClient.DownloadData(_urlPath));

            Dividend _sp = new Dividend();

            //							<tr><td class="dotborder"><span class="font10">
            //这后面的为真正的数据
            string[] strs = _myWebInfo1.Split(new string[] { "							<tr><td class=\"dotborder\"><span class=\"font10\">" }, StringSplitOptions.RemoveEmptyEntries);
            strs = strs[1].Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
            strs = strs[0].Split(new string[] { "<tr>" }, StringSplitOptions.RemoveEmptyEntries);

            Dictionary<string, string> strpairs = new Dictionary<string, string>();
            strpairs.Add("<td class=\"bgcolor\">", "");
            strpairs.Add("\r", "");
            strpairs.Add("<td class=\"dotborder\">", "");
            strpairs.Add("<span class=\"font10\">", "");
            strpairs.Add("</span>", "");
            strpairs.Add("<td class=\"lastbgcolor\">", "");
            strpairs.Add("<td>", "");
            strpairs.Add("<a href=\"#\" title=\"", "");
            strpairs.Add("\">[详情]</a></td></tr></tr>", "");

            foreach (string str in strs)
            {
                string _str = Global.StringReplaces(str, strpairs);
                string[] strs2 = _str.Split(new string[] { "</td>" }, StringSplitOptions.RemoveEmptyEntries);
                _sp.Dividends.Add(DateTime.Parse(strs2[6]), new DividendInfo
                {
                    Dividends = decimal.Parse(strs2[5]) * 10000,
                    DividendPerShare = decimal.Parse(strs2[1]),
                    SplitPerShare = decimal.Parse(strs2[2]) + decimal.Parse(strs2[3])
                });
            }

            _sp.Save(stockCode);
        }

        /// <summary>
        /// 将Dividend融入财务报表中，并保存报表。
        /// 目前只完善年的，对于季度或半年的先不理。
        /// 使用替换的方式，用Dividend替换Statement里面的。
        /// </summary>
        public void DividendInStatements(string stockCode)
        {
            DirectoryInfo _di = new DirectoryInfo(string.Format(@"{0}\{1}\", System.AppDomain.CurrentDomain.BaseDirectory, stockCode));
            FileInfo[] _files = _di.GetFiles();
            SortedList<int, Statement> _fsList = new SortedList<int, Statement>();

            foreach (FileInfo fi in _files)
            {
                if (Regex.IsMatch(fi.Name, @"^\d{4}.json$", RegexOptions.None))
                {
                    Statement _fs = Statement.Load(fi.FullName);
                    _fsList.Add(int.Parse(fi.Name.Substring(0, fi.Name.IndexOf("."))), _fs);
                }
            }
            foreach (KeyValuePair<int, Statement> kvp in _fsList)
            {
                decimal _dividends = 0;
                foreach (KeyValuePair<DateTime, DividendInfo> kvp2 in this.Dividends)
                {
                    //记录的总是上一年的派现金额
                    if ((kvp2.Key.Year - 1) == kvp.Key)
                    {
                        _dividends += kvp2.Value.Dividends;
                    }
                }
                if (_dividends != 0)
                {
                    if (kvp.Value is IndustrialStatements)
                    {
                        ((IndustrialStatements)kvp.Value).Dividends = _dividends;
                    }
                    else
                    {
                        ((FinanceStatements)kvp.Value).Dividends = _dividends;
                    }

                    Console.WriteLine("DividendIn, the statement is: [{0}], and dividends is: [{1}]", kvp.Key, _dividends);
                    kvp.Value.Save(kvp.Key.ToString(), stockCode);
                }
            }
        }
    }
}
